/*
 * @by: VMLY&R
 * @Author: taiming.li
 * @LastEditTime: 2021-09-07 18:32:20
 * @FilePath: /webAudio/src/js/app.js
 * @E-mail: 834777406@qq.com
 */

console.log('This is app.js')

var mousedown = 'mousedown '// 鼠标按下
var mousemove = 'mousemove '// 鼠标移动
var mouseup = 'mouseup '// 鼠标抬起
var mouseout = 'mouseout '// 鼠标移除
var mouse = 'PC'
if (document.hasOwnProperty('ontouchstart') || 'ontouchstart' in window) {
    mousedown = 'touchstart '// 手指按下
    mousemove = 'touchmove '// 手指移动
    mouseup = 'touchend '// 手指抬起
    mouseout = 'touchcancel '// 手指移除
    mouse = 'YD'
}

window.onload = function () {
    var audio = document.getElementById("audio");
    audio.addEventListener('ended', function () {
        audio.play()
        setTimeout(function () { audio.play(); }, 10);
    }, false);
    document.addEventListener('WeixinJSBridgeReady', function () {
        WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
            audio.play()
            WeixinReady()
        })
    }, false)

    var type = 2//1=播放aydio 2=播放webAudio
    var isStart = true

    $('.play').on(mouseup, function () {
        if (type === 1) {
            audio.play()
        } else if (type === 2) {
            request(URL)
            isStart = true
            source.start()
            // 如果想要控制音频的暂停与播放 可使用audioContext.resume 和 suspend 方法
            console.log(source);
        }

    })

    $('.stop').on(mouseup, function () {
        audio.pause()
        isStart = false
        if (source) {
            source.stop()
        }
    })


    var canvas = document.getElementById('canvas')
    ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    var cwidth = canvas.width
    var cheight = canvas.height - 2

    var canvas2 = document.getElementById('canvas2')
    ctx2 = canvas2.getContext('2d');
    canvas2.width = window.innerWidth;
    canvas2.height = window.innerHeight - 100;

    var lastData = Date.now()
    var yuData = Date.now()
    var score = 0
    var imgs = [
        { id: 0, name: 'bg', src: 'img/bg2.jpg' },
        { id: 1, name: 'bullet', src: 'img/bullet.png' },
        { id: 2, name: 'fish', src: 'img/fish.png' },
        { id: 3, name: 'cannon', src: 'img/cannon.png' },
    ]
    var cannon = {
        src: 'img/cannon2.png',
        x: (canvas2.width - 104) / 2,
        y: canvas2.height - 102,
        w: 104,
        h: 102
    }
    var bullets = [
        // {
        //     name: 'bullet',
        //     x: (canvas2.width - 27) / 2,
        //     y: canvas2.height - 110,
        //     w: 27,
        //     h: 87
        // }
    ]
    var fishs = [
        // {
        //     name: 'fish',
        //     x: 0,
        //     y: 10,
        //     w: 64,
        //     h: 64
        // }
    ]
    initGame()

    function initGame() {
        score = 0
        Promise.all(
            imgs.map((item) => {
                // console.log('item2',item)
                return loadImage(item.src)
            })
        ).then((result) => {
            result.map(function (item, index) {
                imgs[index].img = item
            })

            drawGame()
            console.log('imgs', imgs)
        })
    }

    function loadImage(src) {
        //创建promise的实例
        return new Promise((resolve, reject) => {
            var image = new Image();
            image.onload = function () {
                resolve(image)
                // console.log('image加载成功', image)
            }
            image.src = src
        })
    }

    function drawGame() {
        ctx2.clearRect(0, 0, cwidth, cheight);
        ctx2.drawImage(imgs[0].img, 0, 0, cwidth, cheight)
        bullets.forEach(item => {
            ctx2.drawImage(imgs[1].img, item.x, item.y, item.w, item.h)
        })
        fishs.forEach(item => {
            ctx2.drawImage(imgs[2].img, item.x, item.y, item.w, item.h)
        })

        ctx2.drawImage(imgs[3].img, cannon.x, cannon.y)
    }

    function hit() {
        for (let i = 0; i < bullets.length; i++) {
            // console.log(bullets[i])
            for (let k = 0; k < fishs.length; k++) {
                // console.log(fishs[k]);
                if (bullets[i].y < fishs[k].y + fishs[k].h && bullets[i].y > fishs[k].y && bullets[i].x > fishs[k].x && bullets[i].x < fishs[k].x + fishs[k].h) {
                    bullets.splice(i, 1)
                    fishs.splice(k, 1)
                    score++
                    $('.score').html('score：' + score)

                    // console.log('hit!!!');
                }
            }

        }
    }
    // setInterval(() => {
    //     hit()
    // }, 2000);


    /**
     * @method: 获取音频
     * @param {*} url
     */
    // 创建AudioContent对象
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    console.log(audioCtx);
    const URL = 'media/music.mp3';
    var source
    //创建分析器
    var analyser = audioCtx.createAnalyser()
    function request(url) {

        // 创建一个声音源
        source = audioCtx.createBufferSource();

        const request = new XMLHttpRequest();
        request.open('GET', url, true);
        request.responseType = 'arraybuffer';
        request.onload = function () {
            const audioData = request.response; // 请求回来的arraybuffer的音频文件
            // 下面就是解码操作 buffer节点
            console.log('request', request)
            // 异步解码音频文件中的 ArrayBuffer
            audioCtx.decodeAudioData(audioData, function (buffer) {
                // 告诉该源播放何物
                source.buffer = buffer;
                // 低频滤波器
                var biquadFilter = audioCtx.createBiquadFilter();
                // 低音増幅效果
                biquadFilter.type = "lowshelf";
                // 在指定时间内改变音频
                biquadFilter.frequency.setValueAtTime(1000, audioCtx.currentTime);
                biquadFilter.gain.setValueAtTime(25, audioCtx.currentTime);
                // source.connect(biquadFilter)

                // 峰值滤波器
                const filter = audioCtx.createBiquadFilter();
                filter.type = 'peaking'; // 设置类型为峰值滤波器
                filter.Q.value = 1; // 峰值滤波器的带宽
                filter.frequency.value = 1000; // 中心频率
                filter.gain.value = 5; // 增益，单位db
                // analyser.connect(filter)

                // 混响效果
                // 音乐文件-->添加音效（混响，降噪，切换声道，添加3d音效等），绘制音谱，
                // 麦克风-->实时声音大小，根据频率制作动效
                // 麦克风-->声音校正
                // 射击游戏-->碰碰碰
                // 赛马游戏-->驾（驾与吁的判断）
                // 跑酷类游戏-->获取声音跳起躲避障碍物
                // 音量测试类，获取音量大小，出现结果，看看谁是分贝之王
                // 录音生成不同混响及类型音乐转发好友

                source.connect(analyser)
                // 将该源与硬件相连
                analyser.connect(audioCtx.destination);
                // filter.connect(audioCtx.destination);
                source.loop = true;

                drawSpectrum()
            })


            // //创建分析器
            // var analyser = audioCtx.createAnalyser();
            // //将source与分析器链接
            // source.connect(analyser);
            // //将分析器与destination链接，这样才能形成到达扬声器的通路
            // analyser.connect(audioCtx.destination);

        }
        request.send();
    }

    //开始绘制频谱图
    function drawSpectrum() {
        if (!isStart) return

        // 要进行FFT的采样数据的窗口大小
        analyser.fftSize = 512
        var bufferLength = analyser.frequencyBinCount;
        // analyser.frequencyBinCount是时域/频域数据的长度，它是fftSize的一半
        var array = new Uint8Array(analyser.frequencyBinCount);

        var barWidth = cwidth / bufferLength * 1.5;
        var barHeight;

        // console.log('analyser', analyser);
        // 获取频率数组--getByteFrequencyData是对已有的数组元素进行赋值
        analyser.getByteFrequencyData(array);
        var hz = Math.max(...array)
        // console.log('array', array, hz);
        // console.log('hz', hz);
        $('.hz').html('maxHz:' + hz)

        //清理画布
        ctx.clearRect(0, 0, cwidth, cheight);
        //定义一个渐变样式用于画图
        var gradient = ctx.createLinearGradient(0, 0, 0, 300);
        gradient.addColorStop(1, '#0f0');
        gradient.addColorStop(0.5, '#ff0');
        gradient.addColorStop(0, '#f00');
        ctx.fillStyle = gradient;
        //对信源数组进行抽样遍历，画出每个频谱条
        for (var i = 0, x = 0; i < bufferLength; i++) {
            // 根据频率映射一个矩形高度
            barHeight = array[i];

            // 绘制一个矩形
            ctx.fillRect(x, cheight - barHeight, barWidth, barHeight);
            x += barWidth + 2;
        }

        // 移动子弹
        bullets.forEach((item, index) => {
            item.y -= 3
            if (item.y < -item.h) {//小于子弹的高度
                bullets.splice(index, 1)
            }
        })

        // 移动鱼
        fishs.forEach((item, index) => {
            item.x += 2
            item.y += 0.6
            if (item.x > cwidth) {
                fishs.splice(index, 1)
            }
        })


        if (Date.now() - yuData > 1000) {//间隔500ms创建一只鱼
            yuData = Date.now()
            let f = {
                name: 'fish',
                x: Math.floor(Math.random() * 20) -30,
                y: Math.floor(Math.random() * 100),
                w: 64,
                h: 64
            }
            fishs.push(f)
        }

        if (hz > 230) {
            if (Date.now() - lastData > 500) {//两次创建子弹间隔大于2秒
                lastData = Date.now()
                console.log('creat');
                let b = {
                    name: 'bullet',
                    x: Math.floor(Math.random() * (cwidth - 28/2)),
                    // x: (canvas2.width - 27) / 2,
                    y: canvas2.height - 88/2,
                    w: 28/2,
                    h: 88/2
                }
                bullets.push(b)
            }

        }
        hit()
        drawGame()
        requestAnimationFrame(drawSpectrum)
    }

    /**
     * @method: 监听音乐播放，添加滚动控制音量
     */
    audio.addEventListener('play', () => {
        return
        audioCtx = new AudioContext();

        // 解码音频文件,返回结果的buffer为AudioBuffer类型数据
        // 创建MediaElementAudioSourceNode
        let source = audioCtx.createMediaElementSource(audio);

        // 创建GainNode对象的新实例,表示音量的变化
        let gainNode = audioCtx.createGain();
        console.log('gainNode', gainNode);

        // Create variables to store mouse pointer Y coordinate
        // and HEIGHT of screen
        let CurY;
        let HEIGHT = window.innerHeight;

        // Get new mouse pointer coordinates when mouse is moved
        // then set new gain value

        // document.onmousemove = updatePage;
        $(document).on(mousemove, updatePage)

        function updatePage(e) {
            console.log('e', e)
            CurY = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);

            gainNode.gain.value = CurY / HEIGHT;
        }

        // 将AudioBufferSourceNode连接到gainNode，将gainNode连接到destination，这样我们就可以播放音乐并使用鼠标光标调整音量
        source.connect(gainNode);
        gainNode.connect(audioCtx.destination);
    });




}